#include "Logger.h"
#include "TcpServer.h"

#include "TcpClient.h"
#include <memory>
#include <thread>

class Session{
public:
    using Ptr = std::shared_ptr<Session>;
    Session(){};
    ~Session(){};
    void HandleRead(std::shared_ptr<GiSo::TcpConnection> conn,GiSo::Buffer& buffer){
        std::string&& data = buffer.CopyToString();
        GS_INFO("Server {0} Received data: {1}",conn->GetFd(), data);
        buffer.Clear();
        conn->Send("Hello from server!");
    }

    void HandleWriteComplete(std::shared_ptr<GiSo::TcpConnection> conn){
        GS_INFO("Server {0} TcpConnection::HandleWriteComplete", conn->GetFd());
    }

    void HandleClose(std::shared_ptr<GiSo::TcpConnection> conn){
        GS_INFO("Server {0} TcpConnection::HandleClose", conn->GetFd());
    }

    // 连接建立时设置连接的回调
    static bool AddSession(GiSo::TcpConnection::Ptr conn, const GiSo::InetAddress& clientAddr){
        GS_INFO("Server New connection from {0}:{1}", clientAddr.GetIp(),clientAddr.GetPort());
        Session::Ptr session = std::make_shared<Session>();
        conn->SetReadCallback(std::bind(&Session::HandleRead,session,std::placeholders::_1,std::placeholders::_2));
        conn->SetWriteCompleteCallback(std::bind(&Session::HandleWriteComplete,session,std::placeholders::_1));
        conn->SetCloseCallback(std::bind(&Session::HandleClose,session,std::placeholders::_1));
        return true;
    }
};

void RunServer(){
    GiSo::InetAddress addr(1126);
    GiSo::TcpServer server(addr, 3);

    Session session;

    server.SetNewConnectionCallback(Session::AddSession);

    // 启动服务器
    server.Start();
}

void RunClient(){
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    GiSo::TcpClient client;
    if(client.ConnectToServer("127.0.0.1",1126)){
        client.SendData("Hello from client!");
        for(int i=0;i<2;i++){
            if(client.Wait(2000)){
                std::string data = client.ReceiveData();
                GS_INFO("Client received: {0} {1}", data,i);
            }
            else{
                GS_ERROR("Client wait timeout");
            }
        }
    }
    else{
        GS_ERROR("Client connect failed");
    }
    client.Disconnect();
}

int main(){
    std::thread clientThread(RunClient);

    std::thread clientThread2(RunClient);

    RunServer();


}
